package com.ruoyi.topInsectImg.utils.soa;

import com.alibaba.fastjson.JSON;
import com.ruoyi.topInsectImg.utils.HttpClientUtils;
import org.apache.commons.lang3.StringUtils;


import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

/**
 * Author: huanghg
 * Copyright:浙江托普云农科技股份有限公司
 * Update: 2019-07-2019/7/26 14:45
 * Description:
 */
public class SOAClient {
    private static String SOA_APP_URL = "http://api.zjtpyun.com/rest";
    private static String SOA_APP_KEY = "xsny_api";// openapi key
    private static String SOA_APP_SECRET = "f3945$@d";//openapi secret
    private static String doHttpGet(String url, Map<String, Object> params, String type) throws Exception {
        return HttpClientUtils.doGet(url, params, type);
    }

    private static String doHttpPost(String url, Map<String, Object> params, String type) throws Exception {
        return HttpClientUtils.doPost(url, params, type);
    }

    /**
     * 调用 SOA 方法 配置文件必须有 soa.url 字段
     *
     * @param rpcMethod  方法名
     * @param rpcVersion 方法版本
     * @param params     参数的 Map
     * @return
     */
    public static SOAResponse rpcCall(String rpcMethod, String rpcVersion, Map<String, Object> params) {
        return rpcCall(rpcMethod, rpcVersion, "get", params);
    }

    /**
     * @param rpcMethod
     * @param rpcVersion
     * @param params
     * @return
     */
    public static String rpcCallStr(String rpcMethod, String rpcVersion, Map<String, Object> params) {
        return rpcCallStr(rpcMethod, rpcVersion, "get", params);
    }

    /**
     * @param rpcMethod
     * @param rpcVersion
     * @param callMethod
     * @param params
     * @return
     */
    public static String rpcCallStr(String rpcMethod, String rpcVersion, String callMethod, Map<String, Object> params) {
        return rpcCallStr(rpcMethod, rpcVersion, callMethod, params, SOA_APP_URL, SOA_APP_KEY, SOA_APP_SECRET);
    }

    /**
     * 调用SOA方法 配置文件必须有 soa.url 字段
     *
     * @param rpcMethod  方法名
     * @param rpcVersion 方法版本
     * @param callMethod 调用方式 get post
     * @param params     参数 Map
     * @return
     */
    public static SOAResponse rpcCall(String rpcMethod, String rpcVersion, String callMethod, Map<String, Object> params) {
        return rpcCall(rpcMethod, rpcVersion, callMethod, params, SOA_APP_URL, SOA_APP_KEY, SOA_APP_SECRET);
    }

    /**
     *  调用SOA方法 配置文件必须有 soa.url 字段
     *  用于 result 返回的是 list 类型
     * @param rpcMethod 方法名
     * @param rpcVersion 方法版本
     * @param callMethod 调用方式 get，post
     * @param params 参数 map
     * @return 返回对象
     */
    public static SOAResponseList rpcCallList(String rpcMethod, String rpcVersion, String callMethod, Map<String, Object> params) {
        return rpcCallList(rpcMethod, rpcVersion, callMethod, params, SOA_APP_URL, SOA_APP_KEY, SOA_APP_SECRET);
    }



    /**
     * @param rpcMethod
     * @param rpcVersion
     * @param callMethod
     * @param params
     * @param soaUrl
     * @param appKey
     * @param appScret
     * @return 返回字符串
     */
    public static String rpcCallStr(String rpcMethod, String rpcVersion, String callMethod, Map<String, Object> params, String soaUrl, String appKey, String appScret) {
        String type = "http";
        String retStr = "";
        String methodUrl =   (StringUtils.isBlank(rpcMethod)?"":(rpcMethod + "/"))
                + (StringUtils.isBlank(rpcVersion)?"":rpcVersion);
        try {
            params.put("method", rpcMethod);
            params.put("version", rpcVersion);
            params.put("format", "json");
            params.put("app_key", appKey);
            params.put("timestamp", date2Str(new Date()));
            String sign = SignUtils.assembleSign(params, appScret);
            if (StringUtils.isNotBlank(sign)) {
                params.put("sign", sign);
            }
            if (soaUrl.toLowerCase().startsWith("https")) {
                type = "https";
            }
            if (callMethod.equalsIgnoreCase("get")) {
                retStr = doHttpGet(soaUrl, params, type);
            } else {
                retStr = doHttpPost(soaUrl, params, type);
            }

        }catch (Exception e){
            e.printStackTrace();
        }finally {
        }
        return retStr;
    }

    /**
     * 调用SOA方法 最全参数
     *
     * @param rpcMethod  方法名
     * @param rpcVersion 方法版本
     * @param callMethod 调用方式 get post
     * @param params     参数 Map
     * @param soaUrl     调用 soa 地址 根据 http https 自适应
     * @param appKey     签名 key
     * @param appScret   签名秘钥
     * @return 将返回 字符串进行反序列化
     */
    public static SOAResponse rpcCall(String rpcMethod, String rpcVersion, String callMethod, Map<String, Object> params, String soaUrl, String appKey, String appScret) {
        String retStr = rpcCallStr(rpcMethod, rpcVersion, callMethod, params, soaUrl, appKey, appScret);
        SOAResponse response = null;
        if (retStr != null) {
            try {
                if (StringUtils.isBlank(retStr)){
                    return null;
                }
                response = JSON.parseObject(retStr, SOAResponse.class);
            } catch (Exception e) {
                e.printStackTrace();
                response = null;
            }
        }
        return response;
    }

    /**
     * 调用方法，最全参数，用于 result 返回是 list 集合
     * @return result 列表
     */
    public static SOAResponseList rpcCallList(String rpcMethod, String rpcVersion, String callMethod, Map<String, Object> params, String soaUrl, String appKey, String appScret) {
        String retStr = rpcCallStr(rpcMethod, rpcVersion, callMethod, params, soaUrl, appKey, appScret);
        SOAResponseList response = null;
        if (retStr != null) {
            try {
                if (StringUtils.isBlank(retStr)){
                    return null;
                }
                response = JSON.parseObject(retStr, SOAResponseList.class);
            } catch (Exception e) {
                e.printStackTrace();
                response = null;
            }
        }
        return response;
    }



    private static String date2Str(Date date){
        SimpleDateFormat df = null;
        String returnValue = "";

        if (date != null) {
            df = new SimpleDateFormat("yyyyMMddHHmmss");
            returnValue = df.format(date);
        }
        return (returnValue);
    }
}
